#ifndef COMPILE_H
#define COMPILE_H

#include <string>

// Character types
#define LETTER 1
#define DIGIT 2
#define SPECIAL 3

#define EVENT_TOKEN "EVENT"

// Token types
#define IDENTIFIER 1
#define DIGIT 2
#define CONTROL 3
#define RESERVED 4
#define FUNCTION 5
#define VAR0 5
#define VAR1 6
#define VAR2 7

// goto labels
struct label {
    char ident[40];
    char* pos;
};

// goto labels
extern struct label labels[200];

// goto occurence records
extern struct label gotos[200];

// current token buffer
extern char token[2048];

// restorebuf for NextIs
extern char lasttoken[2048];

// int value of token if it's type DIGIT
extern unsigned int token_nvalue;

// type of current token.
extern char token_type;

// This is just crap.
extern char token_subtype;

// ptr -> current location in sourcefile
extern char* src;

// ptr -> generated output code buffer
extern char* code;

// ptr -> current code buffer location
extern char* cpos;

// character-types lookup table
extern char chr_table[256];

// number of arguements to IF ptr
extern char* numargsptr;

// script offset table
extern unsigned int scriptofstbl[1024];

// number of scripts in the VC file
extern int numscripts;
extern int lines;

// Compilation-state flags
extern char inevent;
extern char iex;
extern int funcidx;
extern int numlabels;
extern int numgotos;
extern int _g_varidx;

extern void err(std::string str);
extern std::string GetErrorMessage();
extern bool IsErrorDetected();

extern bool AtEndOfScripts();
extern bool AtTrueWhitespace();
extern char GetCharType();
extern void SetupCharTable();
extern bool AtMultiLineComment();
extern bool AtEndOfMultiLineComment();
extern void SkipToEndOfMultiLineComment();

extern bool TokenIs(char* str);
extern void ParseWhitespace();
extern bool CheckLibFunc();
extern bool SearchVarList();
extern bool GetIdentifier();
extern bool GetNumber();
extern bool GetPunctuation();
extern bool GetString();
extern bool GetToken();
extern bool NextIs(char* str);
extern void Expect(char* str);
extern int ExpectNumber();
extern void EmitC(char c);
extern void EmitW(short w);
extern void EmitD(int w);
extern void EmitString(char* str);
extern void HandleOperand();
extern void EmitOperand();
extern char HandleExpression();
extern void ProcessVar0Assign();
extern void ProcessVar1Assign();
extern void ProcessVar2Assign();
extern void ProcessIf();
extern void ProcessFor0();
extern void ProcessFor1();
extern void ProcessFor();
extern void ProcessWhile();
extern void ProcessSwitch();
extern void ProcessGoto();
extern void ProcessEvent();
extern char* GetLabelAddr(char* str);
extern void ResolveGotos();

extern bool ParseEvent();

extern void Compile();
extern void InitCompileSystem();
extern void _Test_SetSource(char* pointer);
extern void _Test_FreeSource();
extern void _Test_ClearSourceWithoutFreeing();

extern void _Test_EmitInfoDescend();
extern void _Test_EmitInfo(std::string info);
extern void _Test_EmitInfoAscend();

#endif
